import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import axios from 'axios'
import store from './store'
import MessageService from './utils/MessageService.js'
// 导入日志工具
import Logger from './utils/Logger.js'
// 导入用户信息修复工具
import { fixAndCheckUserInfo } from './utils/fixUserInfo.js'

// 应用启动前初始化用户信息，确保始终有有效的用户信息对象
fixAndCheckUserInfo()

// 配置axios创建Vue应用实例
const app = createApp(App)

// 将MessageService挂载到全局属性，方便在组件中通过this.$messageService访问
app.config.globalProperties.$messageService = MessageService
// 提供给组合式API使用
app.provide('messageService', MessageService)

// 将Logger挂载到全局属性，方便在组件中通过this.$logger访问
app.config.globalProperties.$logger = Logger
// 提供给组合式API使用
app.provide('logger', Logger)

// 注册Element Plus图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

// 配置日志级别和上传
Logger.setLogLevel('DEBUG')
// 配置日志上传（后端日志收集接口）
// 使用相对路径，让Logger使用request.js中已配置好baseURL的axios实例
Logger.configureUpload('api/logs/collect', 60000)

// 配置axios
axios.defaults.baseURL = ''

// 请求拦截器 - 记录请求日志
axios.interceptors.request.use(
  config => {
    // 在请求头中添加token
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    
    // 记录API请求日志
    Logger.apiRequest(config.url, config.method, config.params, config.data)
    
    return config
  },
  error => {
    // 记录请求错误
    Logger.error('API请求错误', {
      error: error.message,
      stack: error.stack
    })
    return Promise.reject(error)
  }
)

// 响应拦截器 - 记录响应日志
axios.interceptors.response.use(
  response => {
    // 记录API响应日志
    Logger.apiResponse(response.config.url, response.config.method, response.status, response.data)
    return response
  },
  error => {
    // 处理响应错误，如token过期等
    let errorMessage = '请求失败'
    let errorData = null
    let status = 500
    
    if (error.response) {
      status = error.response.status
      errorData = error.response.data
      errorMessage = `HTTP错误: ${status}`
    } else if (error.request) {
      errorMessage = '网络错误: 服务器无响应'
    } else {
      errorMessage = `请求配置错误: ${error.message}`
    }
    
    // 记录响应错误日志
    Logger.error(errorMessage, {
      status,
      data: errorData,
      config: error.config,
      message: error.message,
      stack: error.stack
    }, true) // 显示错误通知
    
    return Promise.reject(error)
  }
)

// 全局错误处理 - 使用增强版错误处理函数

// 全局未捕获异常处理
window.addEventListener('error', (event) => {
  Logger.fatal('未捕获的全局错误', {
    message: event.message,
    filename: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    error: event.error?.message,
    stack: event.error?.stack
  })
})

// 全局未处理的Promise拒绝
window.addEventListener('unhandledrejection', (event) => {
  Logger.fatal('未处理的Promise拒绝', {
    reason: event.reason?.message || String(event.reason),
    stack: event.reason?.stack
  })
})

// 路由全局钩子 - 记录路由变化
router.beforeEach((to, from, next) => {
  Logger.modules.router.info('路由跳转', {
    from: from.path,
    to: to.path,
    meta: to.meta
  })
  next()
})

router.afterEach((to, from) => {
  Logger.modules.router.info('路由跳转完成', {
    from: from.path,
    to: to.path,
    fullPath: to.fullPath,
    query: to.query
  })
})

// 挂载应用
app.use(router)
app.use(store)
app.use(ElementPlus)

// 记录应用启动信息
Logger.info('应用启动', {
  appName: 'TestPlatform',
  environment: import.meta.env.MODE || 'development',
  version: import.meta.env.VITE_APP_VERSION || 'unknown',
  timestamp: new Date().toISOString()
})

app.mount('#app')

// 全局错误处理
app.config.errorHandler = (err, instance, info) => {
  try {
    // 安全地打印错误信息，避免访问undefined属性
    if (err) {
      // 避免JSON.stringify可能导致的循环引用问题
      try {
        console.error('全局错误:', err.message || err.toString())
        // 尝试获取更多错误上下文信息
        if (err.stack) {
          console.error('错误堆栈:', err.stack)
        }
      } catch (stringifyError) {
        console.error('全局错误: 无法序列化的错误对象')
      }
    } else {
      console.error('全局错误: 未知错误类型')
    }
    
    if (instance) {
      console.error('组件实例:', '组件实例对象')
      // 尝试获取组件名称
      try {
        const componentName = instance.type?.name || instance.type?.__name || '未知组件'
        console.error('组件名称:', componentName)
      } catch (e) {
        console.error('无法获取组件名称')
      }
    }
    
    if (info) {
      console.error('错误信息:', info)
      // 针对特定类型的错误提供更具体的诊断信息
      if (info.includes('render function') && err?.message?.includes('Cannot read properties of undefined')) {
        console.error('诊断信息: 这很可能是在模板中尝试访问未定义对象的属性，请检查组件的props和data定义')
      }
    }
    
    // 显示错误通知
    try {
      // 避免循环引用导致的问题
      const errorMessage = err && (err.message || err.toString()) ? err.message || err.toString() : '未知错误'
      const errorInfo = info || '渲染函数错误'
      
      // 只在开发环境显示详细错误
      if (import.meta.env.DEV) {
        // 针对特定错误提供更具体的提示
        if (errorMessage.includes('Cannot read properties of undefined') && errorInfo.includes('render function')) {
          MessageService.error(`应用发生错误: ${errorMessage}\n\n提示: 这可能是组件中引用了未定义的数据，请检查组件的props或data初始化\n\n错误位置: ${errorInfo}`)
        } else {
          MessageService.error(`应用发生错误: ${errorMessage}\n${errorInfo}`)
        }
      } else {
        MessageService.error('应用发生错误，请刷新页面重试')
      }
    } catch (notifyError) {
      console.error('显示错误通知失败:', notifyError)
    }
    
    // 尝试恢复应用状态
    try {
      // 更智能的错误恢复策略
      const token = localStorage.getItem('token')
      const currentPath = window.location.pathname
      
      // 对于Cannot read properties of undefined错误，可以尝试返回首页而不是简单刷新
      if (token && err?.message?.includes('Cannot read properties of undefined')) {
        setTimeout(() => {
          if (currentPath !== '/' && currentPath !== '/login') {
            router.push('/')
          } else {
            window.location.reload()
          }
        }, 2000)
      } else if (token && currentPath !== '/login') {
        // 其他错误简单刷新
        setTimeout(() => {
          window.location.reload()
        }, 1000)
      }
    } catch (recoveryError) {
      console.error('应用恢复失败:', recoveryError)
    }
  } catch (fatalError) {
    console.error('全局错误处理函数本身发生错误:', fatalError)
  }
}